﻿// CDialogLogScin.cpp: 实现文件
//

#include "pch.h"
#include "HCViewerProgramm.h"
#include "afxdialogex.h"
#include "CDialogLogScin.h"
#include <fstream>
#include <time.h>
#include <regex>
#include <map>
using namespace std;
extern ofstream out;

// CDialogLogScin 对话框

IMPLEMENT_DYNAMIC(CDialogLogScin, CDialogEx)

CDialogLogScin::CDialogLogScin(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_DIALOG_LOG_SCINTILLA, pParent)
{
	m_SearchIndex = 0;
	m_FilterLevel = 0;
	SearchTxt = _T("");
	m_LogEditWnd = NULL;
	m_FindResultWnd = NULL;
}
CDialogLogScin::CDialogLogScin(CWnd* pParent, string fileDir)
	: CDialogEx(IDD_DIALOG_LOG_SCINTILLA, pParent), m_FileDir(fileDir)
{
	m_SearchIndex = 0;
	m_FilterLevel = 0;
	SearchTxt = _T("");
	m_LogEditWnd = NULL;
	m_FindResultWnd = NULL;
}
CDialogLogScin::~CDialogLogScin()
{
	if (m_LogEditWnd)
	{
		delete m_LogEditWnd;
		m_LogEditWnd = NULL;
	}
	if (m_FindResultWnd)
	{
		delete m_FindResultWnd;
		m_FindResultWnd = NULL;
	}
}

void CDialogLogScin::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_CHECK_INFO_SCIN, m_RadioInfo);
	//DDX_Control(pDX, IDC_COMBO_LEVEL, m_ComboLevel);
	DDX_Control(pDX, IDC_EDIT_SEARCH_SCIN, M_EditSearch);
	DDX_Control(pDX, IDC_BUTTON_SEARCH_SCIN, m_SearchBtn);
	//DDX_Control(pDX, IDC_BUTTON_NEXT, m_SearchNext);
	DDX_Control(pDX, IDC_CHECK_ERROR_SCIN, m_RadioError);
	DDX_Control(pDX, IDC_CHECK_DEBUG_SCIN, m_RadioDebug);
	DDX_Control(pDX, IDC_CHECK_INFO_SCIN, m_RadioInfo);
	DDX_Control(pDX, IDC_CHECK_ALL_SCIN, m_RadioAll);
	DDX_Control(pDX, IDC_CHECK_IMPORTANT_SCIN, m_RadioImport);
	DDX_Control(pDX, IDC_CHECK_REG_SCIN, m_RadioReg);
}


BEGIN_MESSAGE_MAP(CDialogLogScin, CDialogEx)
	ON_BN_CLICKED(IDC_BUTTON_SEARCH_SCIN, &CDialogLogScin::OnBnClickedButtonSearchScin)
	ON_BN_CLICKED(IDC_CHECK_INFO_SCIN, &CDialogLogScin::OnBnClickedCheckInfoScin)
	ON_BN_CLICKED(IDC_CHECK_DEBUG_SCIN, &CDialogLogScin::OnBnClickedCheckDebugScin)
	ON_BN_CLICKED(IDC_CHECK_ERROR_SCIN, &CDialogLogScin::OnBnClickedCheckErrorScin)
	ON_BN_CLICKED(IDC_CHECK_ALL_SCIN, &CDialogLogScin::OnBnClickedCheckAllScin)
	ON_BN_CLICKED(IDC_CHECK_IMPORTANT_SCIN, &CDialogLogScin::OnBnClickedCheckImportantScin)
	ON_BN_CLICKED(IDC_CHECK_REG_SCIN, &CDialogLogScin::OnBnClickedRegScin)
	ON_WM_CREATE()
	ON_WM_SIZE()
END_MESSAGE_MAP()


// CDialogLogScin 消息处理程序

void CDialogLogScin::OnBnClickedButtonSearchScin()
{
	// TODO: 在此添加控件通知处理程序代码
	// TODO: 在此添加控件通知处理程序代码
	if (!m_LogEditWnd)
	{
		return;
	}
	CString searchString;
	map<int, string> findInfoMap;
	M_EditSearch.GetWindowText(searchString);
	
	//out << "searchString " << string(CT2A(searchString.GetString())) << endl;
	if (searchString.IsEmpty())
		return;
	//AfxMessageBox(searchString);
	int state = ((CButton*)GetDlgItem(IDC_CHECK_REG_SCIN))->GetCheck();
	if (searchString.Compare(SearchTxt)) {
		int count = m_LogEditWnd->SearchAllHit(searchString, state, findInfoMap);
		SearchTxt = searchString;
		CString matchTime;
		matchTime.Format(_T("%d"), count);
		CString searchResult = SearchTxt + _T("共匹配") + matchTime + _T("次");
		GetDlgItem(IDC_STATIC_SEARCHRESULT)->SetWindowText(searchResult);
		GetDlgItem(IDC_STATIC_SEARCHRESULT)->ShowWindow(SW_SHOW);
		if (m_FindResultWnd)
		{
			m_FindResultWnd->ShowWindow(SW_SHOW);
			m_FindResultWnd->SetResultMap(findInfoMap);
			m_FindResultWnd->ShowFindResult();
		}
	}
	if (state == 1)//正则表达式搜索
	{
		out << "search regex" << endl;
		string pattern = CT2A(searchString.GetString());
		try {
			regex reg(pattern);
			m_LogEditWnd->Search(searchString, 1);

		}
		catch (std::regex_error& e)
		{
			out << "regex error " << e.what() << " error code " << e.code() << std::endl;
			AfxMessageBox(_T("正则表达式错误"));
		}
	}
	else
	{		
		m_LogEditWnd->Search(searchString,0);
	}

}

void CDialogLogScin::OnBnClickedCheckInfoScin()
{
	// TODO: 在此添加控件通知处理程序代码
	if (m_RadioInfo.GetCheck())
		m_FilterLevel |= LV_INFO_SCIN;
	else
		m_FilterLevel &= ~LV_INFO_SCIN;
	FilterLogVector();
	SetLogShow();
}

void CDialogLogScin::OnBnClickedCheckDebugScin()
{
	// TODO: 在此添加控件通知处理程序代码
		// TODO: 在此添加控件通知处理程序代码
	if (m_RadioDebug.GetCheck())
		m_FilterLevel |= LV_DEBUG_SCIN;
	else
		m_FilterLevel &= ~LV_DEBUG_SCIN;
	FilterLogVector();
	SetLogShow();
}

void CDialogLogScin::OnBnClickedCheckErrorScin()
{
	// TODO: 在此添加控件通知处理程序代码
		// TODO: 在此添加控件通知处理程序代码
	if (m_RadioError.GetCheck())
		m_FilterLevel |= LV_ERROR_SCIN;
	else
		m_FilterLevel &= ~LV_ERROR_SCIN;
	FilterLogVector();
	SetLogShow();
}

void CDialogLogScin::OnBnClickedCheckAllScin()
{
	// TODO: 在此添加控件通知处理程序代码
	if (m_RadioAll.GetCheck()) {
		m_FilterLevel = LV_ALL_SCIN;
		m_RadioInfo.SetCheck(0);
		m_RadioError.SetCheck(0);
		m_RadioDebug.SetCheck(0);
		m_RadioImport.SetCheck(0);
		m_RadioInfo.EnableWindow(0);
		m_RadioError.EnableWindow(0);
		m_RadioDebug.EnableWindow(0);
		m_RadioImport.EnableWindow(0);
	}
	else
	{
		m_RadioInfo.EnableWindow(1);
		m_RadioError.EnableWindow(1);
		m_RadioDebug.EnableWindow(1);
		m_RadioImport.EnableWindow(1);
	}
	FilterLogVector();
	SetLogShow();
}
void CDialogLogScin::OnBnClickedRegScin()
{
	SearchTxt = _T("");
}
void CDialogLogScin::OnBnClickedCheckImportantScin()
{
	// TODO: 在此添加控件通知处理程序代码
	if (m_RadioImport.GetCheck()) {
		m_FilterLevel = LV_IMPORTANT_SCIN;
		m_RadioInfo.SetCheck(0);
		m_RadioError.SetCheck(0);
		m_RadioDebug.SetCheck(0);
		m_RadioAll.SetCheck(0);
		m_RadioInfo.EnableWindow(0);
		m_RadioError.EnableWindow(0);
		m_RadioDebug.EnableWindow(0);
		m_RadioAll.EnableWindow(0);
	}
	else
	{
		m_FilterLevel = LV_ALL_SCIN;
		m_RadioInfo.EnableWindow(1);
		m_RadioError.EnableWindow(1);
		m_RadioDebug.EnableWindow(1);
		m_RadioAll.EnableWindow(1);
	}
	FilterLogVector();
	SetLogShow();
}

int CDialogLogScin::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CDialogEx::OnCreate(lpCreateStruct) == -1)
		return -1;
	out << "CDialogLogScin OnCreate" << endl;
	// TODO:  在此添加您专用的创建代码

	return 0;
}
void CDialogLogScin::SetLogShow()
{
	if (!m_LogEditWnd)
	{
		return;
	}
	clock_t start;
	clock_t end;
	SearchTxt = _T("");
	if (m_FindResultWnd)
		m_FindResultWnd->ClearView();
	int i = 0;
	start = clock();
	m_LogEditWnd->ShowLogByVect(m_vLogShow);
	end = clock();
	out << "CDialogLogScin total show log used time" << end - start << endl;
}
void CDialogLogScin::FilterImportantVector(vector<CLogRecord>& vLogRecord)
{
	string pattern = "<Error>|([sS]olid\\[)|(file loaded:)|(点击)";
	try {
		regex reg(pattern);
		smatch sResult;
		for (auto it : m_vLogRecord)
		{
			//匹配成功加入容器
			string cmp_str = it.GetLogContent();
			if (regex_search(cmp_str, sResult, reg))
			{
				vLogRecord.push_back(it);
			}
		}
	}
	catch (std::regex_error& e)
	{
		out << "regex error " << e.what() << " error code " << e.code() << std::endl;
		AfxMessageBox(_T("regex error happened"));
	}
}
void CDialogLogScin::FilterLogVector()
{
	m_vLogShow.clear();
	m_SearchIndex = 0;
	if (m_FilterLevel == LV_ALL_SCIN)
	{
		m_vLogShow = m_vLogRecord;
		return;
	}
	if (m_FilterLevel == LV_IMPORTANT_SCIN)
	{
		FilterImportantVector(m_vLogShow);
		return;
	}
	for (auto it : m_vLogRecord)
	{
		if (m_FilterLevel & LV_INFO_SCIN)
		{
			if (it.GetLogLevel() == LEVEL_INFO)
				m_vLogShow.push_back(it);
		}
		if (m_FilterLevel & LV_DEBUG_SCIN)
		{
			if (it.GetLogLevel() == LEVEL_DEBUG)
				m_vLogShow.push_back(it);
		}
		if (m_FilterLevel & LV_ERROR_SCIN)
		{
			if (it.GetLogLevel() == LEVEL_ERROR)
				m_vLogShow.push_back(it);
		}
	}
}
void CDialogLogScin::AdjustSize(bool isInit)
{
	if (!isInit)
	{
		if (!m_LogEditWnd)
		{
			return;
		}
	}
	RECT rc_window;
	GetClientRect(&rc_window);
	int window_height = rc_window.bottom - rc_window.top;
	int EditWnd_height = (window_height * 7) / 10;
	int window_width = rc_window.right - rc_window.left;
	int EditWnd_Width = (window_width * 9) / 10;
	//out << "window_height " << window_height << "window_width " << window_width << endl;
	RECT rc;
	GetDlgItem(IDC_STATIC_SEARCHRESULT)->GetWindowRect(&rc);
	ScreenToClient(&rc);
	//out << "rc left " << rc.left << " rc right " << rc.right << " rc_top " << rc.top << " rc_bottom " << rc.bottom << endl;
	RECT rc_wnd;
	rc_wnd.left = rc.left;
	rc_wnd.right = rc.left + EditWnd_Width;
	rc_wnd.top = rc.bottom + 10;
	rc_wnd.bottom = rc.bottom + 10 + EditWnd_height;
	RECT rc_wnd_find;
	rc_wnd_find.left = rc_wnd.left;
	rc_wnd_find.right = rc_wnd.left + EditWnd_Width;
	rc_wnd_find.top = rc_wnd.bottom + 10;
	rc_wnd_find.bottom = rc_window.bottom - 5;
	if (isInit)
	{
		//out << "rc_wnd left " << rc_wnd.left << " rc_wnd right " << rc_wnd.right << " rc_wnd top " << rc_wnd.top << " rc_wnd bottom " << rc_wnd.bottom << endl;
		if (!m_LogEditWnd)
		{
			m_LogEditWnd = new CLogEditWnd();
			m_LogEditWnd->Create(WS_EX_CLIENTEDGE, rc_wnd, this);
			m_LogEditWnd->InitLogEdit(12, _T("Fixedsys"));
			m_LogEditWnd->ShowWindow(SW_SHOW);
			m_LogEditWnd->MoveWindow(&rc_wnd);
		}
		else
		{
			m_LogEditWnd->MoveWindow(&rc_wnd);
		}
		if (!m_FindResultWnd)
		{
			m_FindResultWnd = new CFindResultWnd();
			m_FindResultWnd->Create(WS_EX_CLIENTEDGE, rc_wnd, this, ID_SCIN_FIND_RESULT);
			m_FindResultWnd->InitFindEdit(10, _T("Fixedsys"));
			m_FindResultWnd->ShowWindow(SW_HIDE);
			m_FindResultWnd->MoveWindow(&rc_wnd_find);
		}
		else
		{
			m_FindResultWnd->MoveWindow(&rc_wnd_find);
		}
	}
	else
	{
		m_LogEditWnd->MoveWindow(&rc_wnd);
		if (m_FindResultWnd) {
			m_FindResultWnd->MoveWindow(&rc_wnd_find);
		}
	}

}
BOOL CDialogLogScin::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	//out << "CDialogLogScin OnInitDialog" << endl;
	clock_t start;
	clock_t end;
	//AfxMessageBox(_T("CLogDialog init"));
	m_SearchNext.ShowWindow(SW_HIDE);
	AdjustSize(TRUE);
	// TODO: 在此添加额外的初始化代码
	//m_LogViewList.InsertColumn(0, _T("日志内容"), LVCFMT_LEFT, width);
	if (!m_FileDir.empty())
	{
		start = clock();
		int ret = parseLogByFile(m_FileDir, m_vLogRecord);
		end = clock();
		out << "CDialogLogScin total parse time used " << end - start << " ret = " << ret << endl;
		out << "CDialogLogScin m_vLogRecord size " << m_vLogRecord.size() << endl;
		if (!ret)
		{
			//将日志内容插入listctrl控件
			//vector<CLogRecord> vLogRecord;
			//FilterImportantVector(m_vLogShow);
			FilterLogVector();
			SetLogShow();
		}
	}
	GetDlgItem(IDC_STATIC_SEARCHRESULT)->ShowWindow(SW_HIDE);
	return true;
}


void CDialogLogScin::OnSize(UINT nType, int cx, int cy)
{
	CDialogEx::OnSize(nType, cx, cy);
	out << "CDialogLogScin onsize" << endl;
#if 1
	AdjustSize(FALSE);
#endif
	// TODO: 在此处添加消息处理程序代码
}

BOOL CDialogLogScin::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
	// TODO: 在此添加专用代码和/或调用基类
	NMHDR* hdr = (NMHDR*)lParam;
	if (hdr->code == SCN_DOUBLECLICK && hdr->idFrom == ID_SCIN_FIND_RESULT)
	{
		//out << "click line number" << m_FindResultWnd->GetCurrLine() << endl;
		//MessageBox(L"你单击了Button1", L"消息");
		size_t linenum = m_FindResultWnd->GetCurrLine();
		if(linenum>=0)
			m_LogEditWnd->SelectLine(linenum);
	}
	return CDialogEx::OnNotify(wParam, lParam, pResult);
}
